package service

import (
	"context"
	"encoding/json"
	"sale-admin/config/mysql"
	"sale-admin/internal/app/grpc/client"
	"sale-admin/internal/app/grpc/protoc/devicec"
	"sale-admin/internal/app/web/schema"
	"sale-admin/internal/dal"
	"sale-admin/internal/dao"
	"sale-admin/internal/define"
	"sale-admin/internal/models"
	"strconv"
	"strings"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/logx"
	"github.com/samber/lo"
	"gorm.io/gorm"
)

type RobotPayment struct{}

// 获取机器的支付方式，需要兼容积分支付
func (RobotPayment) GetRobotPayments(ctx context.Context, db *gorm.DB, salesID string, PaymentID int) (PaymentTypeMap map[string]int) {
	RobotInfo, err := dao.Robot{}.Detail(ctx, dal.Q, "", salesID)
	if err != nil || RobotInfo == nil || RobotInfo.ID == "" {
		return
	}

	MerchantID := ""
	// 1.查询机器配置的支付方式
	PaymentTypeMap, MerchantID = RobotPayment{}.GetRobotConfiguredPayments(ctx, db, salesID, PaymentID, *RobotInfo)
	// 2.机器未配置时调用商户默认支付方式
	if len(PaymentTypeMap) == 0 {
		PaymentTypeMap = RobotPayment{}.GetRobotDefaultPayments(ctx, db, salesID, MerchantID, PaymentID)
	}

	// 过滤小天才支付
	var filterPaymentTypes = make(map[string]int)
	for k, v := range PaymentTypeMap {
		if k != "12" {
			filterPaymentTypes[k] = v
		}
	}
	PaymentTypeMap = filterPaymentTypes

	// 返回积分支付
	deviceClient, clientErr := client.GetDeviceAdminClient()
	if clientErr != nil {
		logx.Error(context.Background(), "grpc device client error", logx.Err(clientErr))
		return
	}
	// GRPC获取商场位置列表
	deviceReq := &devicec.LocationDetailReq{}
	deviceReq.LocationId = strconv.Itoa(RobotInfo.Areas3)
	deviceRes, err := deviceClient.LocationDetail(context.Background(), deviceReq)
	if deviceRes != nil && deviceRes.Code == 0 && err == nil {
		if deviceRes.Location.PointsId != "" {
			PaymentTypeMap["9"], _ = strconv.Atoi(deviceRes.Location.PointsId) //9 积分支付
		}
	}

	// 指定支付方式时返回指定的支付方式
	if PaymentID > 0 {
		if _, ok := PaymentTypeMap[strconv.Itoa(PaymentID)]; !ok {
			return
		}
		return map[string]int{
			strconv.Itoa(PaymentID): PaymentTypeMap[strconv.Itoa(PaymentID)],
		}
	}
	return
}

// 获取 机器已配置的 支付方式
func (RobotPayment) GetRobotConfiguredPayments(ctx context.Context, db *gorm.DB, salesID string, PaymentID int, RobotInfo models.MaRobot) (
	PaymentTypeMap map[string]int, MerchantID string,
) {
	PaymentTypeMap = make(map[string]int)
	MerchantInfo, _, _ := dao.MerchantConfig{}.GetDetail(ctx, db, RobotInfo.ID)

	// 2 选择支付方式，获取商户的支付方式及支付配置
	PaymentsMap := make(map[string]string)
	// 保证MerchantInfo.PaymentsID必须有值，如果为空，则上面会默认获取平台的支付方式
	for _, v := range strings.Split(MerchantInfo.PaymentsID, ",") {
		PaymentsMap[v] = v
	}
	if RobotInfo.PaymentType1 != "" && RobotInfo.PaymentType1 != "0" {
		if _, ok := PaymentsMap[RobotInfo.PaymentType1]; ok {
			if RobotInfo.Payment1 > 0 {
				PaymentTypeMap[RobotInfo.PaymentType1] = RobotInfo.Payment1
			}
		}
	}
	if RobotInfo.PaymentType2 != "" && RobotInfo.PaymentType2 != "0" {
		if _, ok := PaymentsMap[RobotInfo.PaymentType2]; ok {
			if RobotInfo.Payment2 > 0 {
				PaymentTypeMap[RobotInfo.PaymentType2] = RobotInfo.Payment2
			}
		}
	}
	if RobotInfo.PaymentType3 != "" && RobotInfo.PaymentType3 != "0" {
		if _, ok := PaymentsMap[RobotInfo.PaymentType3]; ok {
			if RobotInfo.Payment3 > 0 {
				PaymentTypeMap[RobotInfo.PaymentType3] = RobotInfo.Payment3
			}
		}
	}
	if RobotInfo.PaymentType4 != "" && RobotInfo.PaymentType4 != "0" {
		if _, ok := PaymentsMap[RobotInfo.PaymentType4]; ok {
			if RobotInfo.Payment4 > 0 {
				PaymentTypeMap[RobotInfo.PaymentType4] = RobotInfo.Payment4
			}
		}
	}
	return PaymentTypeMap, RobotInfo.ID
}

// 获取 商户默认的 支付配置
func (RobotPayment) GetRobotDefaultPayments(ctx context.Context, db *gorm.DB, salesID, merchantID string, selectedPaymentID int,
) (PaymentTypeMap map[string]int) {
	PaymentTypeMap = map[string]int{}

	// 查询商户拥有的支付方式
	merchantConfigInfo, _, _ := dao.MerchantConfig{}.GetDetail(ctx, db, merchantID)
	if merchantConfigInfo.PaymentsID == "" {
		return
	}
	for _, paymentType := range strings.Split(merchantConfigInfo.PaymentsID, ",") {
		// 查询对应的支付类别的具体的支付配置ID
		switch paymentType {
		case define.PaymentType_Wechat: // 微信
			wechatConfig, _ := dao.Payment{}.GetWechatPay(context.Background(), dal.Q, merchantID, 0)
			if len(wechatConfig) > 0 {
				PaymentTypeMap[define.PaymentType_Wechat] = wechatConfig[0].ID
			}
		case define.PaymentType_Alipay: // 支付宝
			alipayInfo, _ := dao.Payment{}.GetAliPay(context.Background(), dal.Q, merchantID, 0)
			if len(alipayInfo) > 0 {
				PaymentTypeMap[define.PaymentType_Alipay] = alipayInfo[0].ID
			}
		case define.PaymentType_AliMicro: // 支付宝人脸
			alipayInfo, _ := dao.Payment{}.GetAliPay(context.Background(), dal.Q, merchantID, 0)
			if len(alipayInfo) > 0 {
				PaymentTypeMap[define.PaymentType_AliMicro] = alipayInfo[0].ID
			}
		case define.PaymentType_XiaoTianCai: // 小天才
			smallInfo, _ := dao.Payment{}.GetXiaotiancaiPay(context.Background(), dal.Q, merchantID, 0)
			if len(smallInfo) > 0 {
				PaymentTypeMap[define.PaymentType_XiaoTianCai] = smallInfo[0].ID
			}
		case define.PaymentType_POS: // POS
			posInfo, _ := dao.Payment{}.GetPOSPay(context.Background(), dal.Q, merchantID, 0)
			if len(posInfo) > 0 {
				PaymentTypeMap[define.PaymentType_POS] = posInfo[0].ID
			}
		case define.PaymentType_Wapp:
			PaymentTypeMap[define.PaymentType_Wapp] = 1
		}
	}
	return
}

// 设置机器支付方式
func (RobotPayment) SetRobotPayments(ctx context.Context, db *gorm.DB, merchantID string, Params schema.RobotPaymentConfig) (
	count int64,
	err error,
) {
	payments, _ := json.Marshal(Params.Payments)
	payments1 := string(payments)

	var myPaymentData []schema.PaymentsData
	if err := json.Unmarshal([]byte(payments1), &myPaymentData); err != nil {
		logx.Error(context.Background(), "SetRobotPayments err", logx.Err(err))
	}

	// 1. 判断是否机器的商户ID是否等于当前的merchant_id
	// 通过GRPC获取机器详情
	req := &devicec.DeviceDetailReq{}
	// 根据Params.SalesID 查询 robot_id
	var RobotInfo models.MaRobot
	db.Model(&models.MaRobot{}).Where("sales_id = ?", Params.SalesID).Find(&RobotInfo)

	req.RobotId = RobotInfo.RobotName
	deviceClient, clientErr := client.GetDeviceAdminClient()
	if clientErr != nil {
		logx.Error(context.Background(), "grpc device client error", logx.Err(clientErr))
		return
	}
	res, err := deviceClient.DeviceDetail(context.Background(), req)
	if res.Device.MerchantId != merchantID && merchantID != "1" {
		err = errorx.New("机器不存在", -1)
		return
	}

	// 2、 查询当前商户拥有的支付方式
	// 定义商户的支付方式
	var MerchantPaymentsID string
	var merchantPaymentsIDArr []string
	db.Model(&models.MaMerchantConfig{}).Where("id = ?", merchantID).Select("payments_id").Find(&MerchantPaymentsID)

	merchantPaymentsIDArr = strings.Split(MerchantPaymentsID, ",")
	// 3. 检测给机器分配的支付方式是否被使用过
	paymentsData := []schema.PaymentsData{}
	for _, v := range myPaymentData {
		exists := lo.Contains(merchantPaymentsIDArr, v.Type)
		if !exists {
			err = errorx.New("当前不支持该支付方式", -1)
			return
		} else {
			// 验证当前商户的具体配置信息
			var configExists bool
			configExists, err = RobotPayment{}.ValidatePaymentConfig(db, v.Type, v.ID)
			if !configExists || err != nil {
				err = errorx.New("没有配置具体的支付参数", -1)
				return
			}
			paymentsData = append(paymentsData, v)
		}
	}

	// 4.开始保存机器配置信息
	if len(paymentsData) > 0 {
		count, err = RobotPayment{}.setPay(db, Params.SalesID, paymentsData)
	}
	return
}

// 设置机器支付方式
func (RobotPayment) setPay(db *gorm.DB, salesID string, paymentsData []schema.PaymentsData) (count int64, err error) {
	RobotConfigData := make(map[string]interface{})
	RobotConfigData["payment_type1"] = "0"
	RobotConfigData["payment_type2"] = "0"
	RobotConfigData["payment_type3"] = "0"
	RobotConfigData["payment_type4"] = "0"
	RobotConfigData["payment1"] = 0
	RobotConfigData["payment2"] = 0
	RobotConfigData["payment3"] = 0
	RobotConfigData["payment4"] = 0

	for k, v := range paymentsData {
		if k == 0 {
			RobotConfigData["payment_type1"] = v.Type
			RobotConfigData["payment1"] = v.ID
		}
		if k == 1 {
			RobotConfigData["payment_type2"] = v.Type
			RobotConfigData["payment2"] = v.ID
		}
		if k == 2 {
			RobotConfigData["payment_type3"] = v.Type
			RobotConfigData["payment3"] = v.ID
		}
		if k == 3 {
			RobotConfigData["payment_type4"] = v.Type
			RobotConfigData["payment4"] = v.ID
		}
	}
	count = db.Model(&models.MaRobot{}).
		Where("sales_id = ?", salesID).
		UpdateColumns(&RobotConfigData).RowsAffected
	if count < 0 {
		err = errorx.New("操作失败", -1)
		return
	}
	return count, err
}

/*
 ** ValidatePaymentConfig 判断支付方式的配置是否存在
 *  payType 支付类型，比如微信，支付宝……
 *  configID 配置id
 */
func (RobotPayment) ValidatePaymentConfig(db *gorm.DB, payType string, configID int) (
	exists bool,
	err error,
) {
	var count int64
	if payType == define.PaymentType_AliMicro {
		payType = define.PaymentType_Alipay
	}
	if payType == define.PaymentType_Stripe2 {
		payType = define.PaymentType_Stripe
	}
	if payType == define.PaymentType_Stripe2 || payType == define.PaymentType_Wapp {
		return true, nil
	}

	db.Model(&models.MaPayment{}).
		Where("payment_type = ?", payType).
		Where("origin_id = ?", configID).
		Count(&count)

	return count == 1, err
}

type SalesPaymentStruct struct {
	MerchantID   string `json:"merchant_id"`
	SalesID      string `json:"sales_id"`
	RobotName    string `json:"robot_name"`
	Areas3       string `json:"areas3"`
	PaymentType1 int    `json:"payment_type1"`
	PaymentType2 int    `json:"payment_type2"`
	PaymentType3 int    `json:"payment_type3"`
	PaymentType4 int    `json:"payment_type4"`
	Payment1     int    `json:"payment1"`
	Payment2     int    `json:"payment2"`
	Payment3     int    `json:"payment3"`
	Payment4     int    `json:"payment4"`
}

type NewSalesPaymentStruct struct {
	SalesID      string              `json:"sales_id"`
	RobotName    string              `json:"robot_name"`
	PaymentTypes []PaymentTypeStruct `json:"payment_types"`
}
type PaymentTypeStruct struct {
	PaymentType int `json:"payment_type"`
}

// [安卓] 获取当前机器的所有支付方式
func (RobotPayment) GetSalesPayments(ctx context.Context, salesID string) (
	res NewSalesPaymentStruct,
	err error,
) {
	db := mysql.NewDB()
	if salesID == "" {
		return
	}
	var result SalesPaymentStruct
	db.Model(&models.MaRobot{}).
		Where("sales_id = ?", salesID).
		Select(
			"merchant_id, robot_name, sales_id, areas3, payment_type1, payment_type2, payment_type3, payment_type4, payment1, payment2, payment3, payment4",
		).
		Take(&result)

	res.RobotName = result.RobotName
	res.SalesID = result.SalesID

	// 查询机器的商户信息
	MerchantInfo, _, err := dao.MerchantConfig{}.GetDetail(ctx, db, result.MerchantID)
	var PaymentsMap = make(map[int]int)
	for _, v := range strings.Split(MerchantInfo.PaymentsID, ",") {
		v, _ := strconv.Atoi(v)
		PaymentsMap[v] = v
	}

	if result.PaymentType1 > 0 && result.Payment1 > 0 {
		// 判断当前支付方式是否合法
		if _, ok := PaymentsMap[result.PaymentType1]; ok {
			res.PaymentTypes = append(res.PaymentTypes, PaymentTypeStruct{
				PaymentType: result.PaymentType1,
			})
		}
	}

	if result.PaymentType2 > 0 && result.Payment2 > 0 {
		if _, ok := PaymentsMap[result.PaymentType2]; ok {
			res.PaymentTypes = append(res.PaymentTypes, PaymentTypeStruct{
				PaymentType: result.PaymentType2,
			})
		}
	}

	if result.PaymentType3 > 0 && result.Payment3 > 0 {
		if _, ok := PaymentsMap[result.PaymentType3]; ok {
			res.PaymentTypes = append(res.PaymentTypes, PaymentTypeStruct{
				PaymentType: result.PaymentType3,
			})
		}
	}

	if result.PaymentType4 > 0 && result.Payment4 > 0 {
		if _, ok := PaymentsMap[result.PaymentType4]; ok {
			res.PaymentTypes = append(res.PaymentTypes, PaymentTypeStruct{
				PaymentType: result.PaymentType4,
			})
		}
	}

	// 取不到，读取【商户已经配置】默认支付方式
	if len(res.PaymentTypes) == 0 {

		// 第二层检测，获取商户默认支付配置
		PaymentTypeMap := RobotPayment{}.GetRobotDefaultPayments(
			context.Background(),
			db,
			salesID,
			result.MerchantID,
			0,
		)
		if len(PaymentTypeMap) == 0 {
			err = errorx.New("商户没有设置支付方式", -1)
			return
		}
		// 有值
		for paymentTypeStr := range PaymentTypeMap {
			paymentType, _ := strconv.Atoi(paymentTypeStr)
			res.PaymentTypes = append(res.PaymentTypes, PaymentTypeStruct{
				PaymentType: paymentType, // 微信
			})
		}
	}
	// 过滤小天才支付
	filterPaymentTypes := []PaymentTypeStruct{}
	for _, v := range res.PaymentTypes {
		if v.PaymentType != 12 {
			filterPaymentTypes = append(filterPaymentTypes, v)
		}
	}
	res.PaymentTypes = filterPaymentTypes

	// 积分支付
	// 初始化GRPC
	deviceClient, clientErr := client.GetDeviceAdminClient()
	if clientErr != nil {
		logx.Error(context.Background(), "grpc device client error", logx.Err(clientErr))
		return
	}

	// GRPC获取商场位置列表
	deviceReq := &devicec.LocationDetailReq{}
	deviceReq.LocationId = result.Areas3
	deviceRes, err := deviceClient.LocationDetail(context.Background(), deviceReq)
	if deviceRes != nil && deviceRes.Code == 0 && err == nil {
		if deviceRes.Location.PointsId != "" {
			res.PaymentTypes = append(res.PaymentTypes, PaymentTypeStruct{
				PaymentType: 9, // 积分支付
			})
		}
	}
	return res, err
}
